/**
 * @brief IPV4 address operation. 
 *
 * @author Huang RuiGuang
 * @date 2008/12/1
 *
 * Herm library
 * Copyright (c) 2008 by Huang RuiGuang(daemon.huang@gmail.com)
 *
 * Permission to use, copy, modify, distribute and sell this software.
 */

#ifndef HERM_SOCKET_ADDREST_H
#define HERM_SOCKET_ADDREST_H

#include <string>
#include "herm/export_symbols.h"
#include "herm/base/utils/types.h"
#include "herm/base/socket/socket_def.h"

namespace herm{
class HERM_API Address
{
public:
	/**
     * @brief Create a empty address.
	 */
	Address();

	/**
     * @brief Create a address that IP is any, and port is\n
	 *        \a port.
	 * @param [port] Binding port that is host byte order.
	 */
	explicit Address(uint16_t port);

	/**
     * @brief Create a address by \a ip & \a port.
     * @param [ip] Binding ip, eg, "10.8.1.9".
	 * @param [port] Binding port that is host byte order.
	 */
	Address(const std::string& ip, uint16_t port);

	/**
     * @brief Create a address by \a ip & \a port.
	 * @note \a ip & \a port are net byte order.
	 */
	Address(uint32_t ip, uint16_t port);
	
	~Address(void);

	bool operator==(const Address& addr) const;
	bool operator!() const;
	operator void *() const;


	void Init();
	void Set(uint16_t port);

	/**
     * @brief Create a address by \a ip & \a port.
     * @param [ip] Binding ip, eg, "10.8.1.9".
	 * @param [port] Binding port that is host byte order.
	 */
	void Set(const std::string& ip, uint16_t port);

	/**
     * @brief Create a address by \a ip & \a port.
	 * @note \a ip & \a port are net byte order.
	 */
	void Set(uint32_t ip, uint16_t port);
    void SetDomain(const std::string& host, int port);

	/**
     * @brief Get string IP.
	 */
	std::string IP() const;

	/**
     * @brief Get net byte order 32bits IP.
	 */
	uint32_t NetIP() const;

	/**
     * @brief Get the port that is host byte order.
	 */
	uint16_t Port() const;

	/**
     * @brief Get the port that is net byte order.
	 */
	uint16_t NetPort() const;

	/**
     * @brief Get address handle.
	 * @return Reference to address handle .
	 */
	const sockaddr_in& SockAddr() const;

	/**
     * @brief Set address handle.
	 * @param [sin] Address handle that is net byte order.
	 */ 
	void SockAddr(const sockaddr_in& sin);
private:
	sockaddr_in m_addr;
};
}

#endif
